package com.xiguanlezz.cn.client.naming.remote;

import com.xiguanlezz.cn.api.naming.pojo.Instance;
import com.xiguanlezz.cn.api.naming.pojo.ServiceInfo;
import com.xiguanlezz.cn.api.naming.utils.NamingUtils;
import com.xiguanlezz.cn.client.naming.core.ServerListManager;
import com.xiguanlezz.cn.client.env.NacosClientProperties;
import com.xiguanlezz.cn.client.naming.cache.ServiceInfoHolder;
import com.xiguanlezz.cn.client.naming.core.ServiceInfoUpdateService;
import com.xiguanlezz.cn.client.naming.remote.grpc.NamingGrpcClientProxy;
import com.xiguanlezz.cn.client.naming.remote.http.NamingHttpClientProxy;

import java.util.Objects;

/**
 * @Author：习惯了种种
 * @CreateDate：2024/11/18 17:24
 * @Description：用于和服务端进行通信的客户端网络代理类
 */
public class NamingClientProxyDelegate implements NamingClientProxy {
    private NamingGrpcClientProxy grpcClient; /* GRPC通信代理对象 */
    private NamingHttpClientProxy httpClient; /* HTTP通信代理对象 */
    private ServerListManager serverListManager; /* Nacos服务端地址列表管理类 */

    // 客户端主动访问服务端，判断服务实例是否更新的组件
    private ServiceInfoUpdateService serviceInfoUpdateService;
    // 客户端关于服务实例的缓存实体类
    private ServiceInfoHolder serviceInfoHolder;


    public NamingClientProxyDelegate(String namespace, NacosClientProperties properties) {
        // 初始化服务端地址列表管理器
        serverListManager = new ServerListManager(namespace, properties);
        grpcClient = new NamingGrpcClientProxy(namespace, serverListManager, properties);
        httpClient = new NamingHttpClientProxy();
    }

    public NamingClientProxyDelegate(String namespace, ServiceInfoHolder serviceInfoHolder, NacosClientProperties properties) {
        // 初始化服务端地址列表管理器
        serverListManager = new ServerListManager(namespace, properties);
        this.serviceInfoHolder = serviceInfoHolder;
        serviceInfoUpdateService = new ServiceInfoUpdateService(properties, serviceInfoHolder, this);
        grpcClient = new NamingGrpcClientProxy(namespace, serverListManager, serviceInfoHolder, properties);
        httpClient = new NamingHttpClientProxy();
    }

    @Override
    public void registerService(String serviceName, String groupName, Instance instance) throws Exception {
        getExecuteClientProxy(instance).registerService(serviceName, groupName, instance);
    }

    @Override
    public void deregisterService(String serviceName, String groupName, Instance instance) throws Exception {
        grpcClient.deregisterService(serviceName, groupName, instance);
    }

    @Override
    public ServiceInfo subscribe(String serviceName, String groupName, String clusters) throws Exception {
        String serviceKey = ServiceInfo.getKey(NamingUtils.getGroupedName(serviceName, groupName), clusters);
        // 启动定时拉取订阅服务的实例信息的任务
        serviceInfoUpdateService.scheduleUpdateIfAbsent(serviceName, groupName, clusters);
        // 先从缓存中获取服务实例信息
        ServiceInfo serviceInfo = serviceInfoHolder.getServiceInfoMap().get(serviceKey);
        if (Objects.isNull(serviceInfo) || !isSubscribed(serviceName, groupName, clusters)) {
            serviceInfo = grpcClient.subscribe(serviceName, groupName, clusters);
        }
        return serviceInfo;
    }

    @Override
    public void unsubscribe(String serviceName, String groupName, String clusters) throws Exception {
        // 停止定时拉取订阅服务的实例信息的任务
        serviceInfoUpdateService.stopUpdateIfContain(serviceName, groupName, clusters);
        grpcClient.unsubscribe(serviceName, groupName, clusters);
    }

    @Override
    public boolean isSubscribed(String serviceName, String groupName, String clusters) throws Exception {
        return grpcClient.isSubscribed(serviceName, groupName, clusters);
    }

    public NamingClientProxy getExecuteClientProxy(Instance instance) {
        if (instance.isEphemeral()) {
            return grpcClient;
        } else {
            return httpClient;
        }
    }
}
